
import * as ol from '../openLayer'
import { markOptionDefaultConfig } from './config'
import { createMarksStyle } from './style'
import { click, pointerMove } from 'ol/events/condition.js'
import { deepAssign } from '@/utils/tools/deepAssign'
import { boundingExtent } from 'ol/extent.js'
/**
 * 图标marks 类，
 * 配置项参考config.js
 */
/**
 * marks 样式参考style.js 样式配置项
 */
export default class OlMarks {
  constructor (_map, _config) {
    this.map = _map
    this.options = deepAssign(markOptionDefaultConfig, _config) //  配置项
    this.clusters = null // 聚合点对象
    this.overlayPopupElement = null // overlayPopup提示框element 对象
    this.overlayPopup = null // overlayPopup提示框overlay 对象
    const overlay = this.map.getOverlayById(this.options.actionOverlayConfig.id)
    if (overlay) {
      this.map.removeOverlay(overlay)
    }
    this.addMarks()
  }

  /**
   * 更新marks,(待开发)
   * @param {*} _map
   * @param {*} _config
   */
  updateOlMars (_map, _config) {
    this.map = _map
    this.options = deepAssign(markOptionDefaultConfig, _config) //  配置项
  }

  /**
   * 添加坐标点
   */
  addMarks () {
    const features = []
    for (const point of this.options.points) {
      // 点的坐标信息
      const coordinates = [point[this.options.lnglatConfig.lng], point[this.options.lnglatConfig.lat]]
      const feature = new ol.Feature({
        geometry: new ol.Point(coordinates),
        name: point.name,
        id: point.id,
        properties: point
      })
      features.push(feature)
    }
    // 创建聚合对象并设置数据源和距离
    const source = new ol.VectorSource({
      features: features

    })
    const clusterSource = new ol.Cluster({
      distance: parseInt(10, 10),
      source: source,
      type: this.options.type,
      geometryName: this.options.layerProperties.id,
    })
    this.clusters = new ol.VectorLayer({
      source: clusterSource,
      style: (feature) => this.setSelectStyle(feature),
      className: 'MarkerLayer',
      properties: this.options.layerProperties
    })
    this.map.addLayer(this.clusters)
    this.attachActionListener()
  }

  /**
   * 添加监听
   */
  attachActionListener () {
    // console.log('ddd=====', this.options)
    if (this.options.actions.length > 0) {
      for (const action of this.options.actions) { //  绑定事件
        const condition = action.type === 'hover' ? pointerMove : click // 默认有点击事件
        const features = []
        for (const point of this.options.points) {
          // 点的坐标信息
          const coordinates = [point[this.options.lnglatConfig.lng], point[this.options.lnglatConfig.lat]]
          const feature = new ol.Feature({
            geometry: new ol.Point(coordinates),
            name: point.name,
            id: point.id,
            properties: point
          })
          // feature.setId('d')
          // feature.setGeometryName('labelPoint')
          features.push(feature)
        }
        const marksEvents = new ol.Select({
          condition: condition,
          hitTolerance: action.hitTolerance || 5, // 命中容差默认是5
          style: (feature) => this.setSelectStyle(feature),
          layers: [this.clusters]
        })
        this.map.addInteraction(marksEvents)
        marksEvents.on('select', (e) => {
          // console.log('点击e', e, '状态', e.target.getActive())
          const selectedfeature = e.selected
          const size = selectedfeature.length
          // let action = e.target.getActive()
          if (size > 0) { //  有数据值
            // console.log('selectedfeature.length', selectedfeature.length, e)
            const featuresArr = selectedfeature[0].get('features')
            if (featuresArr.length > 1) { // 聚合点， 事件触发
              if (this.options.clusterConfig.scatter) { //  聚合点变成单点
                const extent = boundingExtent(
                  featuresArr.map((r) => r.getGeometry().getCoordinates())
                )
                this.map.getView().fit(extent, {
                  duration: this.options.clusterConfig.duration,
                  size: this.options.clusterConfig.size
                })
              } else { // 聚合点点击触发事件
                this.backSelectedPointList(featuresArr, action)
                this.onShowOverlayPopup()
              }
            } else { //  单点
              this.backSelectedPointList(featuresArr, action)
              this.onShowOverlayPopup(action, marksEvents, e)
            }
            // console.log('点击', this.overlayPopupElement, this.overlayPopup)
          }
        })
      }
    }
  }

  /**
   * 显示tip  提示框
   * @param {*} action
   * @param {*} marksEvents
   * @param {*} event
   */
  onShowOverlayPopup (action, marksEvents, event) {
    if (action?.overlayConfig?.show && action?.overlayConfig?.element) { // 如果有overlayElement ,者创建overlayPopup 提示框
      const pixel = event.mapBrowserEvent.pixel_
      const coordinate = this.map.getCoordinateFromPixel(pixel)
      this.handleCreateOverlay(action, marksEvents, coordinate)
    }
  }

  /**
   * popup 创建提示框&删除提示框
   */
  handleCreateOverlay (action, marksEvents, coordinate) {
    let closeEle = null
    if (!this.overlayPopupElement) {
      this.overlayPopupElement = document.createElement('div')
      this.overlayPopupElement.id = this.options.actionOverlayConfig.id
      this.overlayPopupElement.className = `${this.options.actionOverlayConfig.className}`
      this.overlayPopupElement.appendChild(action?.overlayConfig?.element)
      closeEle = document.createElement('div')
      closeEle.className = 'mark-popup-close'
      this.overlayPopupElement.appendChild(closeEle)
      document.body.appendChild(this.overlayPopupElement)
    }
    if (!this.overlayPopup) {
      this.overlayPopup = new ol.Overlay({
        id: this.options.actionOverlayConfig.id,
        element: this.overlayPopupElement,
        offset: this.options.actionOverlayConfig.offset,
        positioning: this.options.actionOverlayConfig.positioning,
        autoPan: {
          animation: {
            duration: 200
          }
        }
      })
      this.map.addOverlay(this.overlayPopup)
    }
    this.overlayPopup.setPosition(coordinate)
    if (closeEle) {
      closeEle.addEventListener('click', () => { // 关闭overlayPopup
        marksEvents.getFeatures().clear() // 清除当前选中状态
        this.map.removeOverlay(this.overlayPopup) // 移除Overlay
        this.overlayPopup = null
        this.overlayPopupElement = null
      })
    }
  }

  /**
   * 返回选中的point 点位数据
   * @param {*} featuresList
   * @param {*} action
   */
  backSelectedPointList (featuresList, action) {
    const pointsList = []
    for (const feature of featuresList) {
      pointsList.push(feature.get('properties'))
    }
    // console.log('pointsList=', pointsList)
    if (pointsList.length > 0) {
      // console.log('mark 点击或者hover 事件', pointsList)
      action.handle(pointsList)
    }
  }

  /**
   * 设置marks 样式
   * @param {*} feature
   * @returns
   */
  setSelectStyle (feature, type = 'unaction') {
    const size = feature.get('features').length
    const styleObj = type === 'action' ? this.options.markSelectStyle : this.options.layerStyle // 默认未选中
    const styleCache = {}
    let style = styleCache[size]
    if (size > 1) {
      if (!style) {
        const customStyle = styleObj.filter(item => item.type === 'clusterMark')[0] || { pointType: 'CircleStyle', style: {} }
        customStyle.style.text = size.toString()
        style = createMarksStyle(customStyle, 'clusterMark')
        styleCache[size] = style
      }
      return style
    } else {
      const status = feature.get('features')[0].get('properties').status
      const legendArr = styleObj.filter(item => item.legend === status) //  使用图例
      let customStyle
      if (legendArr.length > 0) { // 有图例
        customStyle = legendArr[0]
      } else { // 无图例，找type类型为singleMark 点配置
        customStyle = styleObj.filter(item => item.type === 'singleMark')[0] || { pointType: 'CircleStyle', style: {} }
      }
      const markerStyle = createMarksStyle(customStyle)
      styleCache[size] = markerStyle
      return markerStyle
    }
  }
}
